<template>
  <div class="task-manage page-container">
    <el-form
      class="query-form"
      ref="queryForm"
      :model="queryParams"
      :inline="true"
      size="small"
      label-width=""
    >
      <el-form-item class="big-query" label="关键词" prop="key_word">
        <el-input
          v-model="queryParams.key_word"
          placeholder="请输入关键词"
          clearable
          size="small"
          style="width: 240px"
          @keyup.enter.native="handleQuery"
          @clear="handleQuery"
        />
      </el-form-item>
      <el-form-item class="big-query" label="试验状态" prop="status">
        <el-select
          v-model="queryParams.status"
          filterable
          placeholder="请选择"
          @change="handleQuery"
        >
          <el-option label="全部" :value="null" />
          <el-option label="调试中" value="waited" />
          <el-option label="运行中" value="started" />
          <el-option label="已结束" value="finished" />
        </el-select>
      </el-form-item>
      <el-form-item class="big-query" label="运行日期" prop="time">
        <el-date-picker
          v-model="queryParams.time"
          type="daterange"
          value-format="yyyy-MM-dd HH:mm:ss"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
        >
        </el-date-picker>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" size="small" @click="handleQuery"
          >搜索</el-button
        >
        <el-button size="small" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>
    <div class="operate-wrap">
      <el-button
        type="primary"
        @click.stop="openAbDialog()"
        size="small"
        icon="el-icon-plus"
        >新增</el-button
      >
    </div>
    <el-table v-loading="loading" :data="abList">
      <el-table-column label="ID" width="100" prop="id" />
      <el-table-column label="试验名称" prop="name" />
      <el-table-column label="试验层" prop="user_percent">
        <template slot-scope="scope">
          占【全体受众】的{{ scope.row.user_percent }}%
        </template>
      </el-table-column>
      <!-- <el-table-column label="描述" width="160" prop="description" /> -->
      <el-table-column label="试验状态" min-width="120" prop="status">
        <template slot-scope="scope">
          {{getStatus(scope.row.status)}}
        </template>
      </el-table-column>
      <el-table-column label="运行时间" prop="run_time" width="330">
        <template slot-scope="scope">
          {{scope.row.started_at}} - {{scope.row.finished_at  }}
        </template>
      </el-table-column>
      <el-table-column label="操作" width="150" fixed="right">
        <template slot-scope="scope">
          <template v-if="['started','finished'].includes(scope.row.status)">
            <el-button type="text" size="small" @click.stop="toDetail(scope.row)"
            >查看</el-button
          >
          </template>
          <template  v-if="scope.row.status === 'started'">
            <el-button
            type="text"
            size="small"
            @click.stop="stopAbSetting(scope.row)"
            >下线</el-button
          >
          </template>

          <template v-if="scope.row.status === 'waited'">
            <el-button
            type="text"
            size="small"
            @click.stop="toEdit(scope.row)"
            >编辑</el-button
          >
            <el-button
            type="text"
            size="small"
            @click.stop="upAbSetting(scope.row)"
            >上线</el-button
          >
          </template>

          <el-button
            type="text"
            size="small"
            @click.stop="deleteAb(scope.row)"
            :disabled="scope.row.status === 'started'"
            >删除</el-button
          >
        </template>
      </el-table-column>
    </el-table>
    <div class="pagination-wrap">
      <pagination
        v-show="total > 0"
        :total="total"
        :page.sync="queryParams.page"
        :limit.sync="queryParams.page_size"
        @pagination="getTableList"
      />
    </div>
    <el-dialog
      class="add-task-dialog"
      :title="getFormTitle(this.form.formType)"
      :visible.sync="dialogVisible"
      width="800px"
      top="5vh"
      :close-on-click-modal="false"
      @closed="reset"
    >
      <el-form
        ref="form"
        :model="form"
        :rules="rules"
        label-width="120px"
        label-position="right"
        :disabled="form.formType === 'disabled'"
      >
        <h3 class="title">基本信息</h3>
        <el-form-item label="试验名称" prop="name">
          <el-input v-model.trim="form.name"></el-input>
        </el-form-item>
        <el-form-item label="备注" prop="description">
          <el-input
            v-model="form.description"
            type="textarea"
            :rows="3"
            placeholder="请输入内容"
            :maxLength="300"
          >
          </el-input>
        </el-form-item>
        <el-form-item label="运行时长" prop="run_time">
          <el-input-number
            v-model="form.run_time"
            :step="1"
            :min="1"
            :step-strictly="true"
          ></el-input-number
          ><span class="unit">天</span>
        </el-form-item>
        <h3 class="title">选取受众</h3>
        <el-form-item label="受众范围" prop="user_range_type">
          <el-radio-group v-model="form.user_range_type">
            <el-radio label="all">全部受众</el-radio>
            <el-radio label="user_group">属性筛选</el-radio>
          </el-radio-group>
        </el-form-item>
        <template v-if="form.user_range_type==='user_group'">
          <el-form-item label="应用项目/渠道" prop="unionid" class="big-query">
            <el-cascader
            v-model="form.unionid"
            :options="channelOpts"
            :props="{ checkStrictly: true }"
            collapse-tags
            clearable
            filterable
            style="width: 300px;"></el-cascader>
          </el-form-item>
        </template>
        <el-form-item label="占用比例" prop="user_percent">
          <el-input-number
            v-model="form.user_percent"
            :step="1"
            :min="1"
            :max="100"
            controls-position="right"
            :step-strictly="true"
          ></el-input-number>
        </el-form-item>
        <h3 class="title">设置分组</h3>
        <el-form-item class="group-form-item" label-width="0">
          <div class="test-group-list" :class="{disabled:form.formType === 'disabled'}" ref="groupListEle">
            <div class="group-item">
              <h4 class="group-title">分组名称</h4>
              <p>xrf</p>
              <p class="rate">流量比例</p>
              <h5 class="param">参数</h5>
              <div class="param-list">
                <div
                  class="param-item"
                  v-for="(mainValue, index) in abParamList"
                  :key="mainValue.id"
                >
                  <el-select
                    v-model="mainValue.value_type"
                    size="small"
                    style="flex: 0 0 90px;"
                  >
                    <el-option
                      v-for="optionItem in paramOption"
                      :key="optionItem"
                      :value="optionItem"
                      :label="optionItem"
                    ></el-option>
                  </el-select>
                  <el-input
                    placeholder="参数名"
                    v-model="mainValue.key"
                    title=""
                    size="small"
                    :maxLength="50"
                    @blur="() => handleParamKeyChange(mainValue,index)"
                  ></el-input>
                  <i
                    class="el-icon-circle-close delete-param-icon"
                    v-if="form.formType !== 'disabled'"
                    @click.stop="deleteParam(index)"
                  ></i>
                </div>
              </div>
              <div class="add-param" v-if="form.formType !== 'disabled'">
                <span @click="addParamItem">
                  <i class="el-icon-plus"></i>
                  <span>添加参数</span>
                </span>
              </div>
            </div>
            <div
              v-for="(item,index) in abGoupList"
              :key="item.id"
              class="group-item group-compare-item"
            >
              <h4 class="group-title">
                <el-input
                  v-if="item.isEdit"
                  v-model.trim="item.name"
                  size="small"
                  class="name-input"
                  @blur="() => handleNameInputBlur(item)"
                  :maxLength="10"
                ></el-input>
                <template v-else>
                  {{ item.name }}
                  <i class="el-icon-edit" v-if="form.formType !== 'disabled'" @click.stop="editGroupItem(item)"></i>
                </template>
                <i
                  v-if="item.type === 'test'"
                  class="el-icon-close"
                  @click.stop="deleteGroupItem(index)"
                ></i>
              </h4>
              <p style="font-size: 12px;">{{item.xrf || '---'}}</p>
              <p class="rate">
                <el-input-number
                  v-model="item.percent"
                  :step="1"
                  :min="0"
                  :max="100"
                  controls-position="right"
                  :step-strictly="true"
                ></el-input-number>
              </p>
              <h5 class="param">参数值</h5>
              <div class="param-list">
                <div
                  class="param-item"
                  v-for="(param, index) in abParamList"
                  :key="param.id"
                >
                  <el-input v-model="item.ab_values[index]" size="small" @blur="() =>handleParamValueChange(param)"></el-input>
                </div>
              </div>
            </div>
          </div>
          <div class="add-group-btn" v-if="form.formType !== 'disabled'" @click="addGroupItem">
            <i class="el-icon-plus"></i>
            添加试验组
          </div>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button
          type="primary"
          @click="addAbSetting"
          v-if="form.formType !== 'disabled'"
          >确 定</el-button
        >
        <el-button @click="dialogVisible = false">取 消</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import { mapGetters } from 'vuex'
import {
  addAbSetting,
  updateAbSetting,
  getAbtestingList,
  getAbDetail,
  upAbSetting,
  stopAbSetting,
  deleteAbSetting
} from '@/api/ab'
import { getChannelByAppId } from '@/api/system/channel'
import { createUniqueString } from '@/utils/index'
const statusMap = {
  'started': '运行中',
  'finished': '已结束',
  'waited': '调试中'
}
const titlesMap = {
  'add': '新增试验',
  'edit': '编辑试验',
  'disabled': '查看试验'
}
export default {
  data () {
    return {
      abGoupList: [
        {
          id: '1',
          name: '对照组',
          type: 'compare',
          percent: 50,
          isEdit: false,
          ab_values: []
        }
      ],
      channelOpts: [],
      abParamList: [],
      paramOption: ['integer', 'string'],
      queryParams: {
        page: 1,
        page_size: 10,
        key_word: '',
        status: '',
        time: []
      },
      total: 0,
      abList: [],
      currentPage: 1,
      dialogVisible: false,
      loading: false,
      form: {
        name: '',
        description: '',
        run_time: 1,
        user_percent: 50,
        user_range_type: 'user_group',
        unionid: []
      },
      rules: {
        name: [{ required: true, message: '请填写试验名称', trigger: 'blur' }],
        type: [
          { required: true, message: '请选择任务类型', trigger: 'change' }
        ],
        unionid: [
          { required: true, type: 'array', message: '请选择任务类型', trigger: 'change' }
        ],
        icon: [
          { required: true, message: '请选择任务图标', trigger: 'change' }
        ]
      }
    }
  },
  computed: {
    ...mapGetters('zcsd-core', ['permission_projectList']),
    getStatus () {
      return (status) => {
        return statusMap[status] || ''
      }
    },
    getFormTitle () {
      return (type) => {
        return titlesMap[type] || ''
      }
    }
  },
  methods: {
    getChannels () {
      let list = this.permission_projectList.map(item => item.app_id)
      getChannelByAppId({ app_ids: list.join(',') }).then(res => {
        const channelList = res.data.list
        for (const item of this.permission_projectList) {
          item.label = item.name
          item.value = item.app_id + ''
          const list = channelList.filter(item1 => item1.app_id + '' === item.value)
          item.children = list.map(item => ({ label: `${item.name}(${item.channel_id})`, value: item.channel_id }))
        }
        this.channelOpts = this.permission_projectList
      })
    },
    // 增加试验组
    addGroupItem () {
      const index = this.abGoupList.length
      const backUp = this.abParamList.map(() => '')
      const item = {
        id: createUniqueString(),
        name: '试验组' + index,
        type: 'test',
        percent: 50,
        isEdit: false,
        ab_values: backUp
      }
      this.abGoupList.push(item)
      this.$nextTick(() => {
        this.$refs.groupListEle.scrollLeft =
          this.$refs.groupListEle.scrollWidth
      })
    },
    // 删除试验组
    deleteGroupItem (index) {
      this.abGoupList.splice(index, 1)
    },
    // 编辑试验组
    editGroupItem (item) {
      if (this.form.formType === 'disabled') {
        return
      }
      item.isEdit = true
    },
    // 增加参数
    addParamItem () {
      if (this.form.formType === 'disabled') {
        return
      }
      const param = {
        id: createUniqueString(),
        value_type: 'integer',
        key: ''
      }
      this.abParamList.push(param)
    },
    deleteParam (index) {
      this.abParamList.splice(index, 1)
      this.abGoupList.forEach(item => {
        item.ab_values.splice(index, 1)
      })
    },
    handleParamKeyChange (item) {
      if (item.key === '') {
        return this.msgError('名称不能为空')
      }
      if (
        this.abParamList.some(
          (it) => it.id !== item.id && it.key === item.key
        )
      ) {
        item.key = ''
        return this.msgError('存在同名参数')
      }
    },
    handleParamValueChange (item) {
      // if (Number(item.value) > 0) {
      //   item.value = Number(item.value) / 1000
      // }
    },
    handleNameInputBlur (item) {
      if (item.name === '') {
        return this.msgError('名称不能为空')
      }
      if (
        this.abGoupList.some(
          (group) => group.id !== item.id && group.name === item.name
        )
      ) {
        return this.msgError('存在同名分组')
      }
      item.isEdit = false
    },
    openAbDialog (row) {
      this.abParamList = [{
        id: createUniqueString(),
        value_type: 'integer',
        key: ''
      }]
      this.abGoupList = [
        {
          id: '1',
          name: '对照组',
          type: 'compare',
          percent: 50,
          isEdit: false,
          ab_values: ['']
        }
      ]
      this.form = {
        formType: 'add',
        name: '',
        description: '',
        run_time: 1,
        user_percent: 50,
        user_range_type: 'user_group'
      }
      this.dialogVisible = true
    },
    // 获取列表数据
    getTableList () {
      this.loading = true
      const { time, ...other } = this.queryParams
      const queryParams = { ...other,
        ...{
          started_time_begin: time[0] || '',
          started_time_end: time[1] || ''
        } }

      getAbtestingList(queryParams)
        .then((res) => {
          this.abList = res.data.ab_testings
          this.total = res.data.total || 0
        })
        .finally(() => {
          this.loading = false
        })
    },
    // 点击搜索
    handleQuery () {
      this.queryParams.page = 1
      this.getTableList()
    },
    // 重置
    resetQuery () {
      this.resetForm('queryForm')
      this.handleQuery()
    },
    // 上线
    upAbSetting ({ id, name }) {
      const { page: pageIndex, page_size: pageSize } = this.queryParams
      this.$confirm(`是否确认上线该试验？试验名称:${name}`, '警告', {
        type: 'warning'
      }).then(() => {
        upAbSetting(id).then(() => {
          this.msgSuccess(`上线成功`)
          this.queryParams.page = this.getCurrentPage({
            total: this.total,
            pageSize,
            pageIndex
          })
          this.getTableList()
        })
      })
    },
    // 停止试验
    stopAbSetting ({ id, name }) {
      const { page: pageIndex, page_size: pageSize } = this.queryParams
      this.$confirm(`是否确认下线该试验？试验名称:${name}`, '警告', {
        type: 'warning'
      }).then(() => {
        stopAbSetting(id).then(() => {
          this.msgSuccess(`下架成功`)
          this.queryParams.page = this.getCurrentPage({
            total: this.total,
            pageSize,
            pageIndex
          })
          this.getTableList()
        })
      })
    },
    // 删除试验
    deleteAb ({ id, name }) {
      const { page: pageIndex, page_size: pageSize } = this.queryParams
      this.$confirm(`是否确认删除该试验？试验名称:${name}`, '警告', {
        type: 'warning'
      }).then(() => {
        deleteAbSetting(id).then(() => {
          this.msgSuccess(`删除成功`)
          this.queryParams.page = this.getCurrentPage({
            total: this.total,
            pageSize,
            pageIndex
          })
          this.getTableList()
        })
      })
    },
    // 新增试验
    addAbSetting () {
      this.$refs.form.validate((valid) => {
        if (valid) {
          const ab_variants = this.getAbVariants()
          const total = ab_variants.reduce((total, cur) => {
            return total + Number(cur.percent)
          }, 0)
          if (total > 100) {
            return this.msgError('流量总比例超过100')
          }
          const requestParam = {
            ...this.form,
            ...{
              ab_variants
            }
          }
          if (this.form.user_range_type === 'user_group') {
            requestParam.ab_user_groups = [
              {
                'key': 'appid',
                'operator': '=',
                'value': this.form.unionid[0] + ''
              }
            ]
            if (this.form.unionid[1]) {
              requestParam.ab_user_groups.push({
                'key': 'unionid',
                'operator': '=',
                'value': this.form.unionid[1]
              })
            }
          }
          if (!this.form.id) {
            addAbSetting(requestParam).then((res) => {
              this.msgSuccess('新增试验成功')
              this.dialogVisible = false
              this.getTableList()
            })
          } else {
            updateAbSetting(this.form.id, requestParam).then(() => {
              this.msgSuccess('编辑试验成功')
              this.dialogVisible = false
              this.getTableList()
            })
          }
        }
      })
    },
    getAbVariants () {
      return this.abGoupList.map((item) => {
        item.ab_variables = item.ab_values.map((value, index) => ({
          value,
          value_type: this.abParamList[index].value_type,
          key: this.abParamList[index].key
        }))
        return item
      })
    },
    formatAbVariants (ab_variants) {
      const ab_variables = ab_variants[0]?.ab_variables || []
      this.abParamList = ab_variables.map(item => ({
        id: createUniqueString(),
        value_type: item.value_type,
        key: item.key
      })
      )
      this.abGoupList = ab_variants.map((item, index) => {
        item.isEdit = false
        item.ab_values = (item.ab_variables || []).map((it) => it.value)
        return item
      })
    },
    getAbDetail (id) {
      getAbDetail(id).then((res) => {
        const { ab_variants, ...other } = res.data.ab_testing
        this.formatAbVariants(ab_variants)
        if (other.ab_user_groups && other.ab_user_groups.length) {
          other.unionid = [other.ab_user_groups[0].value]
          if (other.ab_user_groups[1]) {
            other.unionid.push(other.ab_user_groups[1].value)
          }
        }
        this.form = Object.assign(this.form, other)
        this.dialogVisible = true
      })
    },
    toDetail ({ id }) {
      this.form.formType = 'disabled'
      this.getAbDetail(id)
    },
    toEdit ({ id }) {
      this.form.formType = 'edit'
      this.getAbDetail(id)
    },
    reset () {
      this.resetForm('form')
    }
  },
  created () {
    this.handleQuery()
    this.getChannels()
  }
}
</script>
<style lang="scss" scoped>
.pagination-wrap {
  padding: 20px 0;
}
.add-task-dialog {
  .unit {
    margin-left: 10px;
  }
  .el-col {
    .el-input-number--medium {
      width: 100%;
    }
  }
  h3.title {
    font-size: 14px;
    font-weight: bold;
    margin-bottom: 12px;
  }
  .group-form-item {
    ::v-deep .el-form-item__content {
      display: flex;
      column-gap: 6px;
    }
    .test-group-list {
      max-width: calc(100% - 130px);
      overflow-x: auto;
      white-space: nowrap;
      &.disabled{
        max-width:fit-content;
      }
      .group-item {
        display: inline-block;
        margin-right: 6px;
        width: 280px;
        padding: 12px;
        border: 1px solid #ccc;
        vertical-align: middle;
        +.group-item {
          width: 200px;
        }
        .group-title {
          position: relative;
          margin-bottom: 12px;
          .el-icon-close {
            position: absolute;
            right: -3px;
            top: 6px;
            font-size: 18px;
            cursor: pointer;
          }
          .el-icon-edit {
            cursor: pointer;
          }
          .name-input {
            width: 70%;
          }
        }
        .el-input-number--medium {
          width: 100%;
        }
        .param-item {
          display: flex;
          align-items: center;
          margin-bottom: 8px;
          &:last-child {
            margin-bottom: 0px;
          }
          .el-select {
            margin-right: 6px;
          }
        }
        .add-param {
          display: flex;
          justify-content: center;
          align-items: center;
          color: #409eff;
          cursor: pointer;
        }
      }
      .group-compare-item {
        padding-bottom: 48px;
      }
    }
    .add-group-btn {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 130px;
      color: #409eff;
      border: 1px solid #ccc;
      cursor: pointer;
      user-select: none;
    }
    .delete-param-icon {
      font-size: 20px;
      color: #999;
      margin-left: 6px;
      cursor: pointer;
    }
  }
}
</style>
